/*
*******************************************************************************************************?
**??Copyright?(C)?2023,?苏州检易生物科技有限公司?
**??All?rights?reserved.?
**?
**??FileName:?????  	can.c
**??Description:	
**??Author:????????	?
**  Version				v0.1
**??Date:???????    	2023-02-20
**	Function List：?
**??History:?????????
*********************************************************************************************************
*/


/*
*********************************************************************************************************
*                                              	调试开关
*********************************************************************************************************
*/


/*
*********************************************************************************************************
*                                             INCLUDE FILES
*********************************************************************************************************
*/
#include "BspCan.h"



/*
*********************************************************************************************************
*                                              	宏定义
*********************************************************************************************************
*/
/*
*********************************************************************************************************
*                                              	结构体定义
*********************************************************************************************************
*/
/*
*********************************************************************************************************
*                                              	函数原型声明
*********************************************************************************************************
*/

/*
*********************************************************************************************************
*                                              	全局变量定义
*********************************************************************************************************
*/
/*
*********************************************************************************************************
*                                              	模块静态变量定义
*********************************************************************************************************
*/

CanRxMsg Rx0Message;
CanRxMsg Rx1Message;
void(*CanRx0_Handle)(uint16_t ID,uint8_t *Dat,uint8_t Len); 
void(*CanRx1_Handle)(uint16_t ID,uint8_t *Dat,uint8_t Len);

/*
*********************************************************************************************************
*                                              	函数定义
*********************************************************************************************************
*/
uint8_t BspCan1_Init(TypeDefBspCanStruct *CAN_p)
{
	CanRx0_Handle = CAN_p->CanRx0_Handle;
	CanRx1_Handle = CAN_p->CanRx1_Handle;
	GPIO_InitTypeDef GPIO_InitStructure;
	CAN_InitTypeDef  CAN_InitStructure;
	CAN_FilterInitTypeDef  CAN_FilterInitStructure;	
	NVIC_InitTypeDef NVIC_InitStructure;
	
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);                   											 
  RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN1, ENABLE);
	
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
	GPIO_Init(GPIOA, &GPIO_InitStructure);	
	GPIO_InitStructure.GPIO_Pin =GPIO_Pin_11;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;	//上拉输入
	GPIO_Init(GPIOA, &GPIO_InitStructure);
	
	CAN_InitStructure.CAN_TTCM = DISABLE;	 
	CAN_InitStructure.CAN_ABOM = DISABLE;	  
	CAN_InitStructure.CAN_AWUM = DISABLE;
	CAN_InitStructure.CAN_NART = ENABLE;	
	CAN_InitStructure.CAN_RFLM = DISABLE;	 
	CAN_InitStructure.CAN_TXFP = DISABLE;	
	CAN_InitStructure.CAN_Mode = CAN_Mode_Normal;	 
	CAN_InitStructure.CAN_SJW =   CAN_SJW_1tq;	
	CAN_InitStructure.CAN_BS1 =   CAN_BS1_9tq; 
	CAN_InitStructure.CAN_BS2 =   CAN_BS2_8tq;
	CAN_InitStructure.CAN_Prescaler = 8;  //250k
	CAN_Init(CAN1, &CAN_InitStructure); 	//36*(1+5+6)/3=1M

/* 过滤器初始化 */
	//CAN_FilterInitTypeDef  CAN_FilterInitStructure;	
	CAN_FilterInitStructure.CAN_FilterNumber = 0;	  
	CAN_FilterInitStructure.CAN_FilterMode = CAN_FilterMode_IdMask; 
	CAN_FilterInitStructure.CAN_FilterScale = CAN_FilterScale_32bit; 
	CAN_FilterInitStructure.CAN_FilterIdLow = (CAN_p->NodeID << 5) | (0X0600 << 5);  //过滤器底字节（16Bit）
	CAN_FilterInitStructure.CAN_FilterIdHigh = (0X0080 << 5);  //过滤器高字节（16Bit）
	CAN_FilterInitStructure.CAN_FilterMaskIdLow = 0X0000;
	CAN_FilterInitStructure.CAN_FilterMaskIdHigh = 0X0000;
	CAN_FilterInitStructure.CAN_FilterFIFOAssignment = CAN_Filter_FIFO0;
	CAN_FilterInitStructure.CAN_FilterActivation = ENABLE; 
	CAN_FilterInit(&CAN_FilterInitStructure);
	
	/* Enable the USART1 Interrupt */
	//中断优先级NVIC设置
	NVIC_InitStructure.NVIC_IRQChannel = USB_LP_CAN1_RX0_IRQn;  //TIM3中断
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 6;  //先占优先级0级
	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;  //从优先级3级
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ通道被使能
	NVIC_Init(&NVIC_InitStructure);  //初始化NVIC寄存器

	CAN_ITConfig(CAN1, CAN_IT_FMP0, ENABLE);
	
	return 0;
}

uint8_t Can1SendData(uint16_t StdId,uint8_t *Buff,uint8_t Len)
{
//	uint8_t i;
	CanTxMsg TxMsg;
	uint8_t Index;
	uint8_t MsgBox = 0;
	if(Len > 8)
	return 0x05;
	TxMsg.StdId = StdId;
	TxMsg.DLC = Len;
	TxMsg.IDE = CAN_Id_Standard;
	TxMsg.RTR = CAN_RTR_Data;
	TxMsg.ExtId = 0;
	for(Index = 0;Index < Len;Index++)
	{
		TxMsg.Data[Index] = Buff[Index];
	} 
CAN1_REPETA_TX: 
		MsgBox = CAN_Transmit(CAN1, &TxMsg);
	  if(MsgBox == CAN_TxStatus_NoMailBox)
			 goto CAN1_REPETA_TX;
	return MsgBox;
}
void USB_LP_CAN1_RX0_IRQHandler(void)
{
	if(CAN_GetITStatus(CAN1,CAN_IT_FMP0) == SET)
	{
		CAN_Receive(CAN1,CAN_FIFO0,&Rx0Message);
		if(CanRx0_Handle != 0)
			CanRx0_Handle(Rx0Message.StdId,Rx0Message.Data,Rx0Message.DLC);
	}
}
void CAN1_RX1_IRQHandler(void)
{
	if(CAN_GetITStatus(CAN1,CAN_IT_FMP1) == SET)
	{
		CAN_Receive(CAN1,CAN_FIFO1,&Rx1Message);
		CanRx1_Handle(Rx1Message.StdId,Rx1Message.Data,Rx1Message.DLC);
	}
}
uint8_t BspDeviceID_ReadID(void)
{
	uint8_t DeviceID = 0;
	/*拨码开关的1-8分别是
	A15 B3 B4 B5 B6 B7 B8 B9*/
	GPIO_InitTypeDef GPIOX;
	//PB3默认为JTDO功能若需要使用IO功能，需要开启复用，步骤为开启复用时钟，关闭异步追踪，调用GPIO_PinRemapConfig函数，需要注意如果再次调用GPIOA GPIOB接口，会使得PB3 PA15引脚变回JTAG的引脚
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB|RCC_APB2Periph_GPIOA| RCC_APB2Periph_AFIO,ENABLE);//使能了 GPIOB 和 GPIOA 的时钟 并启用AFIO，
	DBGMCU->CR = DBGMCU->CR & ~((uint32_t)1<<5);
	GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable, ENABLE);//
	GPIOX.GPIO_Pin = GPIO_Pin_9 | GPIO_Pin_8 | GPIO_Pin_7 | GPIO_Pin_6 |
									GPIO_Pin_5 | GPIO_Pin_4 | GPIO_Pin_3 ;
	GPIOX.GPIO_Mode = GPIO_Mode_IPU;
	GPIOX.GPIO_Speed = GPIO_Speed_2MHz;
	GPIO_Init(GPIOB,&GPIOX);
	
	GPIOX.GPIO_Pin = GPIO_Pin_15;
	GPIO_Init(GPIOA,&GPIOX);
	
	if((GPIOA->IDR & GPIO_Pin_15) == 0)
	{
		DeviceID |= 0X01;
	}
	if((GPIOB->IDR & GPIO_Pin_3) == 0)
	{
		DeviceID |= 0X02;
	}
	if((GPIOB->IDR & GPIO_Pin_4) == 0)
	{
		DeviceID |= 0X04;
	}
	if((GPIOB->IDR & GPIO_Pin_5) == 0)
	{
		DeviceID |= 0X08;
	}
	if((GPIOB->IDR & GPIO_Pin_6) == 0)
	{
		DeviceID |= 0X10;
	}
	if((GPIOB->IDR & GPIO_Pin_7) == 0)
	{
		DeviceID |= 0X20;
	}
	if((GPIOB->IDR & GPIO_Pin_8) == 0)
	{
		DeviceID |= 0X40;
	}
	if(DeviceID == 0)
		 DeviceID = 0X31;
	
//	return CLOSE_LOOP_CAN_ID_BASE|DeviceID;
	return DeviceID;
}
	
